package com.ray.life;

import java.io.IOException;
import java.util.List;

import android.content.Context;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationManager;
import android.util.Log;

import com.google.android.maps.GeoPoint;

public class LocationHelper {
    private static final String TAG = "LocationHelper";

    public static final double MILLION = 1e6;

    public static final GeoPoint TAIWAN_CENTER = new GeoPoint((int) (23.97 * LocationHelper.MILLION),
            (int) (120.98 * LocationHelper.MILLION));

    public static GeoPoint getGeoPoint(final Location loc) {
        int lat = (int) (loc.getLatitude() * LocationHelper.MILLION);
        int lon = (int) (loc.getLongitude() * LocationHelper.MILLION);
        return new GeoPoint(lat, lon);
    }

    public static String performGeocode(Context context, String locationName) {
        Log.i(TAG, "location name = " + locationName);

        String result = "Unable to Geocode - " + locationName;
        Geocoder geocoder = new Geocoder(context);
        try {
            List<Address> addresses = geocoder.getFromLocationName(locationName, 1);
            if (addresses != null) {
                result = addresses.get(0).toString();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return result;
    }

    public static GeoPoint getGeoPointByAddress(Context context, String addr) {
        Log.i(TAG, "address : " + addr);
        Geocoder geocoder = new Geocoder(context);
        GeoPoint geoPoint = null;
        try {
            List<Address> addresses = geocoder.getFromLocationName(addr, 1);
            if ((addresses != null) && (addresses.size() > 0)) {
                Address addrObj = addresses.get(0);
                geoPoint = new GeoPoint((int) (addrObj.getLatitude() * LocationHelper.MILLION), (int) (addrObj.getLongitude() * LocationHelper.MILLION));
            }
        } catch (IOException e) {
            geoPoint = null;
            e.printStackTrace();
        }
        return geoPoint;
    }

    public static String GeoPointToString(GeoPoint gp) {
        String value = "";
        try {
            if (gp != null) {
                double geoLatitude = (int) gp.getLatitudeE6() / MILLION;
                double geoLongitude = (int) gp.getLongitudeE6() / MILLION;
                value = String.valueOf(geoLatitude) + "," + String.valueOf(geoLongitude);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return value;
    }

    public static Location getLocation(LocationManager lm) {
        Location location = null;
        try {
            Criteria criteria = new Criteria();
            // setting accuracy to fine, may return no value, so mark it
            // criteria.setAccuracy(Criteria.ACCURACY_FINE);
            criteria.setAltitudeRequired(false);
            criteria.setBearingRequired(false);
            criteria.setCostAllowed(false);
            criteria.setPowerRequirement(Criteria.POWER_LOW);
            criteria.setSpeedRequired(false);

            String providerName = lm.getBestProvider(criteria, true);
            location = lm.getLastKnownLocation(providerName);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return location;
    }

    public static float[] getDistance(GeoPoint gpSrc, GeoPoint gpDest) {
        float[] result = new float[3];

        if (gpDest == null) {
            return null;
        }

        Location.distanceBetween(gpSrc.getLatitudeE6() / MILLION, gpSrc.getLongitudeE6() / MILLION, gpDest.getLatitudeE6() / MILLION, gpDest.getLongitudeE6() / MILLION, result);
        return result;
    }
}
